using System;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Web.UI;

namespace Altairis.Web.UI.WebControls {

    /// <summary>
    /// This class represents FormView, which determines its mode based on QueryString parameter set by ModeSelectorField property. If parameter is missing or empty, switches itself into Insert mode.
    /// </summary>
    public class AutoModeFormView : FormView {

        /// <summary>
        /// Gets or sets URL to redirect after one of Cancel, Delete, Update or Insert commands is performed. May be overriden by command-specific properties.
        /// </summary>
        /// <value>The default redirect URL.</value>
        [Category("Redirect URLs"), UrlProperty(), Description("Gets or sets URL to redirect after one of Cancel, Delete, Update or Insert commands is performed. May be overriden by command-specific properties.")]
        public string DefaultRedirectUrl {
            get { return (string)this.ViewState["DefaultRedirectUrl"]; }
            set { this.ViewState["DefaultRedirectUrl"] = value; }
        }

        /// <summary>
        /// Gets or sets URL to redirect after "Cancel" command is performed.
        /// </summary>
        /// <value>The cancel redirect URL.</value>
        [Category("Redirect URLs"), UrlProperty(), Description("Gets or sets URL to redirect after \"Cancel\" command is performed.")]
        public string CancelRedirectUrl {
            get { return (string)this.ViewState["CancelRedirectUrl"]; }
            set { this.ViewState["CancelRedirectUrl"] = value; }
        }

        /// <summary>
        /// Gets or sets URL to redirect after "Delete" command is performed.
        /// </summary>
        /// <value>The delete redirect URL.</value>
        [Category("Redirect URLs"), UrlProperty(), Description("Gets or sets URL to redirect after \"Delete\" command is performed.")]
        public string DeleteRedirectUrl {
            get { return (string)this.ViewState["DeleteRedirectUrl"]; }
            set { this.ViewState["DeleteRedirectUrl"] = value; }
        }

        /// <summary>
        /// Gets or sets URL to redirect after "Update" command is performed.
        /// </summary>
        /// <value>The update redirect URL.</value>
        [Category("Redirect URLs"), UrlProperty(), Description("Gets or sets URL to redirect after \"Update\" command is performed.")]
        public string UpdateRedirectUrl {
            get { return (string)this.ViewState["UpdateRedirectUrl"]; }
            set { this.ViewState["UpdateRedirectUrl"] = value; }
        }

        /// <summary>
        /// Gets or sets URL to redirect after "Insert" command is performed.
        /// </summary>
        /// <value>The insert redirect URL.</value>
        [Category("Redirect URLs"), UrlProperty(), Description("Gets or sets URL to redirect after \"Insert\" command is performed.")]
        public string InsertRedirectUrl {
            get { return (string)this.ViewState["InsertRedirectUrl"]; }
            set { this.ViewState["InsertRedirectUrl"] = value; }
        }

        /// <summary>
        /// Gets or sets name of QueryString field used to determine FormView mode. If empty, name of first DataKey is used.
        /// </summary>
        /// <value>The mode selector field.</value>
        [Category("Behavior"), Description("Gets or sets name of QueryString field used to determine FormView mode. If empty, name of first DataKey is used.")]
        public string ModeSelectorField {
            get { return (string)this.ViewState["ModeSelectorField"]; }
            set { this.ViewState["ModeSelectorField"] = value; }
        }

        /// <summary>
        /// Gets or sets the page title in Insert mode.
        /// </summary>
        /// <value>The insert page title.</value>
        [Category("Page title"), Description("Gets or sets the page title in Insert mode.")]
        public string InsertPageTitle {
            get { return (string)this.ViewState["InsertPageTitle"]; }
            set { this.ViewState["InsertPageTitle"] = value; }
        }

        /// <summary>
        /// Gets or sets the page title in Edit mode.
        /// </summary>
        /// <value>The edit page title.</value>
        [Category("Page title"), Description("Gets or sets the page title in Edit mode.")]
        public string EditPageTitle {
            get { return (string)this.ViewState["EditPageTitle"]; }
            set { this.ViewState["EditPageTitle"] = value; }
        }

        /// <summary>
        /// Gets or sets the page title in ReadOnly mode.
        /// </summary>
        /// <value>The read only page title.</value>
        [Category("Page title"), Description("Gets or sets the page title in ReadOnly mode.")]
        public string ReadOnlyPageTitle {
            get { return (string)this.ViewState["ReadOnlyPageTitle"]; }
            set { this.ViewState["ReadOnlyPageTitle"] = value; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="AutoModeFormView"/> class.
        /// </summary>
        public AutoModeFormView() {
            // Hook up the relevant events
            this.Init += new EventHandler(AutoModeFormView_Init);
            this.ItemCommand += new FormViewCommandEventHandler(AutoModeFormView_ItemCommand);
            this.ItemInserted += new FormViewInsertedEventHandler(AutoModeFormView_ItemInserted);
            this.ItemUpdated += new FormViewUpdatedEventHandler(AutoModeFormView_ItemUpdated);
            this.ItemDeleted += new FormViewDeletedEventHandler(AutoModeFormView_ItemDeleted);
            this.Load += new EventHandler(AutoModeFormView_Load);
        }

        /// <summary>
        /// Handles the Load event of the AutoModeFormView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        void AutoModeFormView_Load(object sender, EventArgs e) {
            switch (this.CurrentMode) {
                case FormViewMode.Edit:
                    if (!string.IsNullOrEmpty(this.EditPageTitle)) this.Page.Title = this.EditPageTitle;
                    break;
                case FormViewMode.Insert:
                    if (!string.IsNullOrEmpty(this.InsertPageTitle)) this.Page.Title = this.InsertPageTitle;
                    break;
                case FormViewMode.ReadOnly:
                    if (!string.IsNullOrEmpty(this.ReadOnlyPageTitle)) this.Page.Title = this.ReadOnlyPageTitle;
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// Handles the ItemInserted event of the AutoModeFormView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.FormViewInsertedEventArgs"/> instance containing the event data.</param>
        void AutoModeFormView_ItemInserted(object sender, FormViewInsertedEventArgs e) {
            string redirectUrl = string.IsNullOrEmpty(this.InsertRedirectUrl) ? this.DefaultRedirectUrl : this.InsertRedirectUrl;
            if (!string.IsNullOrEmpty(redirectUrl)) this.Page.Response.Redirect(redirectUrl);
        }

        /// <summary>
        /// Handles the ItemDeleted event of the AutoModeFormView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.FormViewDeletedEventArgs"/> instance containing the event data.</param>
        void AutoModeFormView_ItemDeleted(object sender, FormViewDeletedEventArgs e) {
            string redirectUrl = string.IsNullOrEmpty(this.DeleteRedirectUrl) ? this.DefaultRedirectUrl : this.DeleteRedirectUrl;
            if (!string.IsNullOrEmpty(redirectUrl)) this.Page.Response.Redirect(redirectUrl);
        }

        /// <summary>
        /// Handles the ItemUpdated event of the AutoModeFormView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.FormViewUpdatedEventArgs"/> instance containing the event data.</param>
        void AutoModeFormView_ItemUpdated(object sender, FormViewUpdatedEventArgs e) {
            string redirectUrl = string.IsNullOrEmpty(this.UpdateRedirectUrl) ? this.DefaultRedirectUrl : this.UpdateRedirectUrl;
            if (!string.IsNullOrEmpty(redirectUrl)) this.Page.Response.Redirect(redirectUrl);
        }

        /// <summary>
        /// Handles the ItemCommand event of the AutoModeFormView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.FormViewCommandEventArgs"/> instance containing the event data.</param>
        void AutoModeFormView_ItemCommand(object sender, FormViewCommandEventArgs e) {
            if (e.CommandName.Equals("Cancel", StringComparison.OrdinalIgnoreCase)) {
                string redirectUrl = string.IsNullOrEmpty(this.CancelRedirectUrl) ? this.DefaultRedirectUrl : this.CancelRedirectUrl;
                if (!string.IsNullOrEmpty(redirectUrl)) this.Page.Response.Redirect(redirectUrl);
            }
        }

        /// <summary>
        /// Handles the Init event of the AutoModeFormView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        void AutoModeFormView_Init(object sender, EventArgs e) {
            if (this.DesignMode) return;      // do nothing in design mode
            if (this.Page.IsPostBack) return; // do nothing on postback

            // Read field name
            string fieldName = this.ModeSelectorField;
            if (string.IsNullOrEmpty(fieldName) && this.DataKeyNames.Length != 0) fieldName = this.DataKeyNames[0];
            if (string.IsNullOrEmpty(fieldName)) return; // do nothing if no field name found

            // Switch to insert mode for empty field
            if (string.IsNullOrEmpty(this.Page.Request.QueryString[fieldName])) this.ChangeMode(FormViewMode.Insert);
        }

    }

}